{
 "cells": [
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## 3分钟Python学会sorted排序函数"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "***sorted函数用于对数据排序***\n",
    "\n",
    "sorted(iterable[, key][, reverse])\n",
    "\n",
    "sorted函数有三个参数：  \n",
    "* iterable：必选，待排序的集合，可以是list、tuple、set、dict等\n",
    "* reverse：可选，默认是False升序排列，如果为True则降序排列\n",
    "* key：可选，这是一个函数，返回一个key，用于排序的比较\n",
    "\n",
    "注意：sorted函数不会修改原始列表，而是会返回新的列表\n",
    "\n",
    "官方文档：https://docs.python.org/zh-cn/3/howto/sorting.html\n",
    "\n",
    "微信公众号：蚂蚁学Python"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### 1、简单排序"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 1,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "[1, 2, 3, 4, 5]"
      ]
     },
     "execution_count": 1,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "## 简单的升序排序\n",
    "sorted([5, 2, 3, 1, 4])"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 2,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "[5, 4, 3, 2, 1]"
      ]
     },
     "execution_count": 2,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "## 简单的降序排列\n",
    "sorted([5, 2, 3, 1, 4], reverse=True)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### 2、使用key按照字符串的长度排序"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 3,
   "metadata": {},
   "outputs": [],
   "source": [
    "fruits = ['lime', 'blueberry', 'plum', 'avocado']"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 4,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "['avocado', 'blueberry', 'lime', 'plum']"
      ]
     },
     "execution_count": 4,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "# 对于字符串，默认是按字母排序\n",
    "sorted(fruits)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 5,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "['lime', 'plum', 'avocado', 'blueberry']"
      ]
     },
     "execution_count": 5,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "# 按照每个元素的长度len排序\n",
    "sorted(fruits, key=lambda x : len(x))"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 6,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "['lime', 'plum', 'avocado', 'blueberry']"
      ]
     },
     "execution_count": 6,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "# 因为key要求是一个函数，可以简写一下\n",
    "sorted(fruits, key=len)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "体会一下key:  \n",
    "* 这是一个函数\n",
    "* 输入：集合的每个元素\n",
    "* 返回：用于排序对比的值"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### 3、对元组的列表进行排序"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 7,
   "metadata": {},
   "outputs": [],
   "source": [
    "# 比如这个列表可能是从文件读取后的\n",
    "student_tuples = [\n",
    "    ('john', 'boy', 15),\n",
    "    ('jane', 'girl', 12),\n",
    "    ('dave', 'boy', 10)\n",
    "]"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 8,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "[('dave', 'boy', 10), ('jane', 'girl', 12), ('john', 'boy', 15)]"
      ]
     },
     "execution_count": 8,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "# 按照每个元组的第三个元素：年龄进行排序\n",
    "sorted(student_tuples, key=lambda student: student[2])"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### 4、对字典列表排序"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 9,
   "metadata": {},
   "outputs": [],
   "source": [
    "student_dicts = [\n",
    "    {\"name\":'john', \"sex\":'boy', \"age\":15},\n",
    "    {\"name\":'jane', \"sex\":'girl', \"age\":12},\n",
    "    {\"name\":'dave', \"sex\":'boy', \"age\":10}\n",
    "]"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 10,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "[{'name': 'dave', 'sex': 'boy', 'age': 10},\n",
       " {'name': 'jane', 'sex': 'girl', 'age': 12},\n",
       " {'name': 'john', 'sex': 'boy', 'age': 15}]"
      ]
     },
     "execution_count": 10,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "# 按照每个元组的第三个元素：年龄进行排序\n",
    "sorted(student_dicts, key=lambda student: student[\"age\"])"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### 5、对字典的值做排序"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 11,
   "metadata": {},
   "outputs": [],
   "source": [
    "student_dicts = {\n",
    "    'john': {\"sex\":'boy', \"age\":15},\n",
    "    'jane': {\"sex\":'girl', \"age\":12},\n",
    "    'dave': {\"sex\":'boy', \"age\":10}\n",
    "}\n",
    "\n",
    "# 注意：字典本身是无序的，所以只能先转成有序列表"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 12,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "{'john': {'sex': 'boy', 'age': 15},\n",
       " 'jane': {'sex': 'girl', 'age': 12},\n",
       " 'dave': {'sex': 'boy', 'age': 10}}"
      ]
     },
     "execution_count": 12,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "student_dicts"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 13,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "['dave', 'jane', 'john']"
      ]
     },
     "execution_count": 13,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "# 这样只能对字典的KEY排序\n",
    "sorted(student_dicts)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 14,
   "metadata": {},
   "outputs": [],
   "source": [
    "# 先获取key-value的列表形式\n",
    "student_dicts_items = student_dicts.items()"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 15,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "dict_items([('john', {'sex': 'boy', 'age': 15}), ('jane', {'sex': 'girl', 'age': 12}), ('dave', {'sex': 'boy', 'age': 10})])"
      ]
     },
     "execution_count": 15,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "student_dicts_items"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 16,
   "metadata": {},
   "outputs": [],
   "source": [
    "# 取每个元素的第二个分量元素值，然后再获取年龄\n",
    "student_dicts_items = sorted(student_dicts_items, key=lambda x: x[1]['age'])"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 17,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "[('dave', {'sex': 'boy', 'age': 10}),\n",
       " ('jane', {'sex': 'girl', 'age': 12}),\n",
       " ('john', {'sex': 'boy', 'age': 15})]"
      ]
     },
     "execution_count": 17,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "student_dicts_items"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "别想转回字典，记住字典是无序的！"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 18,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "{'dave': {'sex': 'boy', 'age': 10},\n",
       " 'jane': {'sex': 'girl', 'age': 12},\n",
       " 'john': {'sex': 'boy', 'age': 15}}"
      ]
     },
     "execution_count": 18,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "dict(student_dicts_items)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": []
  }
 ],
 "metadata": {
  "kernelspec": {
   "display_name": "Python 3",
   "language": "python",
   "name": "python3"
  },
  "language_info": {
   "codemirror_mode": {
    "name": "ipython",
    "version": 3
   },
   "file_extension": ".py",
   "mimetype": "text/x-python",
   "name": "python",
   "nbconvert_exporter": "python",
   "pygments_lexer": "ipython3",
   "version": "3.7.4"
  }
 },
 "nbformat": 4,
 "nbformat_minor": 2
}
